
from bf_parsedoc2 import *


def beval(x, d):
    #print(repr(x))
    if type(x) is Num:
        return x.n
    elif type(x) is String:
        return x.s
    elif type(x) is RawList:
        return RawList(beval(m, d) for m  in x.l)
    elif type(x) is RawTuple:

        return RawTuple([beval(m, d) for m  in x.l], x.hascomma)
    elif type(x) is Word:
        return d[x.s]
    elif x[0] == "Onum":
        return x[1].n
    elif x[0] == "Ostring":
        return x[1].s
    elif x[0] == "Orawlist":
        return RawList(beval(m, d) for m  in x[1].l)
    elif x[0] == "Orawtuple":
        #print("99999")
        return RawTuple([beval(m, d) for m  in x[1].l], x[1].hascomma)
    elif x[0] == "Oword":
        if x[1].s == "True":
            return True
        elif x[1].s == "False":
            return False
        return d[x[1].s]
    elif x[0] == "Oexp2":
        data = x[1]
        f = data["2f"]
        x = data["2x"]
        y = data["2y"]
        if f[1] == "call":
            x = beval(x, d)
            y = beval(y, d)
            return x(y, d)
        elif f[1] == "+":
            x = beval(x, d)
            y = beval(y, d)
            return x+y
        elif f[1] == "*":
            x = beval(x, d)
            y = beval(y, d)
            return x*y
        elif f[1] == "-":
            x = beval(x, d)
            y = beval(y, d)
            return x-y
        elif f[1] == "/":
            x = beval(x, d)
            y = beval(y, d)
            return x/y
        elif f[1] == "//":
            x = beval(x, d)
            y = beval(y, d)
            return x//y
        elif f[1] == "%":
            x = beval(x, d)
            y = beval(y, d)
            return x%y
        elif f[1] == "==":
            x = beval(x, d)
            y = beval(y, d)
            return x==y
        elif f[1] == "!=":
            x = beval(x, d)
            y = beval(y, d)
            return x!=y
        elif f[1] == ">":
            x = beval(x, d)
            y = beval(y, d)
            return x>y
        elif f[1] == "<":
            x = beval(x, d)
            y = beval(y, d)
            return x<y
        elif f[1] == ">=":
            x = beval(x, d)
            y = beval(y, d)
            return x>=y
        elif f[1] == "<=":
            x = beval(x, d)
            y = beval(y, d)
            return x<=y
        else:
            print(99, f)
            0/0
    else:
        print(x)


def _print(x, d):
    print(*x.l)

def _input(x, d):
    return input(*x.l)

def _int(x, d):
    return int(*x.l)

def _range(x, d):
    return range(*x.l)



def interpret(l, d=None):
    if d is None:
        d = {"print": _print,
        "input": _input,
        "int": _int,
        "range": _range,}
    for part in l:
       # print(part)
        if part[0] == "Oexp2":
            beval(part, d)
        elif part[0] == "Lassign":
            xl = part[1]['x']
            y = part[1]['y']
            y = beval(y, d)
            for x in xl:
                if x[0] == 'Oword':
                    d[x[1].s] = y
            #print(part)
        elif part[0] == "Pif":
            ifx = part[1]['ifx'][1]['x']
            ifb = part[1]['ifb'][1]
            ifx = beval(ifx, d)
            if ifx == False:
                pass
            elif ifx == True:
                #print(ifb)
                interpret(ifb)
            else:
                print(ifx)
                raise Exception('if True False')
        elif part[0] == "Pifelse":
            ifx = part[1]['ifx'][1]['x']
            ifb = part[1]['ifb'][1]
            elseb = part[1]['elseb'][1]
            ifx = beval(ifx, d)
            if ifx == False:
                interpret(elseb)
            elif ifx == True:
                #print(ifb)
                interpret(ifb)
            else:
                print(ifx)
                raise Exception('if True False')

        elif part[0] == "Pifelif":
            #pprint(part)
            ifx = part[1]['ifx'][1]['x']
            ifb = part[1]['ifb'][1]
            elifbl = [da[1] for da in part[1]['elifb']]
            elifxl = [da[1]['x'] for da in part[1]['elifx']]
            elifbl = [ifb]+elifbl[::-1]
            elifxl = [ifx]+elifxl[::-1]
            for x, b in zip(elifxl, elifbl):
                #print('judge', x)
                x = beval(x, d)
                if x == False:
                    continue
                elif x == True:
                #print(ifb)
                    interpret(b)
                    break
                else:
                    print(x)
                    raise Exception('if True False')
        elif part[0] == "Pifelifelse":
            #pprint(part)
            ifx = part[1]['ifx'][1]['x']
            ifb = part[1]['ifb'][1]
            elifbl = [da[1] for da in part[1]['elifb']]
            elifxl = [da[1]['x'] for da in part[1]['elifx']]
            elifbl = [ifb]+elifbl[::-1]
            elifxl = [ifx]+elifxl[::-1]
            #pprint(elifbl)
            #pprint(elifxl)
            for x, b in zip(elifxl, elifbl):
                #print('judge', x)
                x = beval(x, d)
                if x == False:
                    continue
                elif x == True:
                #print(ifb)
                    interpret(b)
                    break
                else:
                    print(x)
                    raise Exception('if True False')
            else:
                elseb = part[1]['elseb'][1]
                interpret(elseb)
        elif part[0] == "Pfor":

            forx = part[1]['forxl'][1]['x']
            forl = part[1]['forxl'][1]['l']
            forb = part[1]['forb'][1]
            forl = beval(forl, d)
            for i in forl:
                d2 = d
                d2[forx[1].s] = i
                interpret(forb, d2)

        else:
            assert 0, part[1]
            pass
            #pprint(part)


def test(s):
    doc = scan(s)
    show(doc)
    r = parsedoc(doc.l)
    showr(r)
    interpret(r)

def tes(s):
    pass

from pprint import pprint


if __name__ == "__main__":
    test('''
a = 1
b = 1
for i in range(10):
    print(a)
    c = a + b
    a = b
    b = c


''')


    tes('''
if 0 > 1:
    print('so many cars')
elif 0 > 2:
    print('good')
elif 0 > 5:
    print('nice')
elif 0 > 6:
    print('chef')
elif 1 == 1:
    print('her')
''')
    tes('''
a = int(input("num of cars: "))
b = a * 4
print("wheels:", b)
if a > 5:
    print('so many cars')
elif a > 2:
    print('good')
''')

















